#include "tcp_socket.hpp"
#include<unistd.h>
#include<signal.h>

//多进程实现服务端

void create_worker(TcpSocket new_sock)
{
  //创建进程
  pid_t pid=fork();
  if(pid<0){
    perror("fork error!\n");
    new_sock.Close();
    return;
  }
  else if(pid>0){
    //父进程只用来接收新建连接，子进程处理收发数据
    new_sock.Close();
    return;
  }
  else{
    //子进程实现数据处理
    while(1){
      //接收数据
      std::string buf;
      bool ret = new_sock.Recv(&buf);
      if(ret==false){
        //数据接受失败
        new_sock.Close();
        exit(-1) ;   //该子进程退出
      }
      //接收成功
      std::cout<<"client say: "<<buf<<std::endl;

      //发送数据
      buf.clear();
      std::cout<<"server say: ";
      fflush(stdout);
      std::cin>>buf;
      ret=new_sock.Send(buf);
      if(ret==false)
      {
        new_sock.Close();
        perror("send error!\n");
        exit(-1);
      }
      //发送成功
    }
  }
  exit(-1);
}

int main(int argc,char* argv[])
{
  if(argc!=3){
    std::cout<<"./tcp_srv1.cc 192.168.75.128 9000";
    return -1;
  }

  std::string cli_ip=argv[1];
  uint16_t cli_port=std::stoi(argv[2]);

  signal(SIGCHLD,SIG_IGN);   //忽略进程退出返回值

  TcpSocket srv_sock;
  //创建套接字
  assert(srv_sock.Socket());
  //绑定地址信息
  assert(srv_sock.Bind(cli_ip,cli_port));
  
  //开始监听
  assert(srv_sock.Listen());
  
  while(1){
  //循环建立新连接
  TcpSocket newsock;  //为每一个客户端创建套接字
  //保存新建连接的客户端信息
  std::string cip;
  uint16_t cport;
  bool ret = srv_sock.Accept(&newsock,&cip,&cport);
  if(ret==false){
    //连接失败，继续下一个连接
    continue;
  }
  //连接成功
  std::cout<<"client ---> "<<cip<<":"<<cport<<"connect success!"<<std::endl;

  //创建多进程来实现
  //收发数据
  create_worker(newsock);
  }

  //关闭套接字
  srv_sock.Close();
  return 0;
}

